import time
import json
from django.utils.deprecation import MiddlewareMixin
from .models import APICallStatistics
from django.contrib.auth.models import AnonymousUser

class APIStatisticsMiddleware(MiddlewareMixin):
    """API调用统计中间件"""
    
    def process_request(self, request):
        # 记录请求开始时间
        request.start_time = time.time()
        
        # 获取请求数据
        if request.method in ['POST', 'PUT', 'PATCH']:
            try:
                request_data = json.loads(request.body)
            except:
                request_data = None
        else:
            request_data = None
            
        request.request_data = request_data

    def process_response(self, request, response):
        # 只记录API请求
        if not request.path.startswith('/v1/'):
            return response

        # 计算响应时间
        response_time = (time.time() - request.start_time) * 1000  # 转换为毫秒

        # 获取响应数据
        try:
            response_data = json.loads(response.content)
        except:
            response_data = None

        # 创建统计记录
        try:
            # 检查用户是否为匿名用户
            user = None if isinstance(request.user, AnonymousUser) else request.user
            
            APICallStatistics.objects.create(
                path=request.path,
                method=request.method,
                status_code=response.status_code,
                response_time=response_time,
                ip_address=self.get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', ''),
                user=user,
                request_data=request.request_data,
                response_data=response_data
            )
        except Exception as e:
            # 记录统计信息失败时不影响正常响应
            print(f'Failed to create API call statistics: {str(e)}')

        return response

    def get_client_ip(self, request):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip 